home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / WindowMaker / src / superfluous.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-03-29  |  18.5 KB  |  800 lines

  1. /*
  2.  *  Window Maker window manager
  3.  * 
  4.  *  Copyright (c) 1997, 1998 Alfredo K. Kojima
  5.  *  Copyright (c) 1997, 1998 Dan Pascu
  6.  * 
  7.  *  This program is free software; you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation; either version 2 of the License, or
  10.  *  (at your option) any later version.
  11.  *
  12.  *  This program is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License
  18.  *  along with this program; if not, write to the Free Software
  19.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 
  20.  *  USA.
  21.  */
  22.  
  23. #include "wconfig.h"
  24.  
  25. #include <X11/Xlib.h>
  26. #include <X11/Xutil.h>
  27.  
  28. #include <stdlib.h>
  29. #include <unistd.h>
  30. #include <math.h>
  31. #include <time.h>
  32.  
  33. #include <wraster.h>
  34.  
  35. #include "WindowMaker.h"
  36. #include "screen.h"
  37. #include "superfluous.h"
  38. #include "dock.h"
  39. #include "wcore.h"
  40. #include "framewin.h"
  41. #include "window.h"
  42. #include "icon.h"
  43. #include "appicon.h"
  44.  
  45.  
  46. extern WPreferences wPreferences;
  47.  
  48.  
  49. #ifdef SPEAKER_SOUND
  50. static void
  51. play(Display *dpy, int pitch, int delay)
  52. {
  53.     XKeyboardControl kc;
  54.     
  55.     kc.bell_pitch = pitch;
  56.     kc.bell_percent = 50;
  57.     kc.bell_duration = delay;
  58.     XChangeKeyboardControl(dpy, KBBellPitch|KBBellDuration|KBBellPercent,&kc);
  59.     XBell(dpy, 50);
  60.     XFlush(dpy);
  61.     wusleep(delay);
  62. }
  63. #endif
  64.  
  65.  
  66.  
  67. #ifdef DEMATERIALIZE_ICON
  68. void
  69. DoKaboom(WScreen *scr, Window win, int x, int y)
  70. {
  71.     RImage *icon;
  72.     RImage *back;
  73.     RImage *image;
  74.     Pixmap pixmap;
  75.     XImage *ximage;
  76.     GC gc;
  77.     XGCValues gcv;
  78.     int i;
  79.     int w, h;
  80.     int run;
  81.     XEvent event;
  82.  
  83.     h = w = wPreferences.icon_size;
  84.     if (x < 0 || x + w > scr->scr_width || y < 0 || y + h > scr->scr_height)
  85.     return;
  86.  
  87.     icon = RCreateImageFromDrawable(scr->rcontext, win, None);
  88.     if (!icon)
  89.     return;
  90.     
  91.     gcv.foreground = scr->white_pixel;
  92.     gcv.background = scr->black_pixel;
  93.     gcv.graphics_exposures = False;
  94.     gcv.subwindow_mode = IncludeInferiors;
  95.     gc = XCreateGC(dpy, scr->w_win, GCForeground|GCBackground|GCSubwindowMode
  96.                   |GCGraphicsExposures, &gcv);
  97.  
  98.  
  99.     XGrabServer(dpy);
  100.     RConvertImage(scr->rcontext, icon, &pixmap);
  101.     XUnmapWindow(dpy, win);
  102.  
  103.     ximage = XGetImage(dpy, scr->root_win, x, y, w, h, AllPlanes, ZPixmap);
  104.     XCopyArea(dpy, pixmap, scr->root_win, gc, 0, 0, w, h, x, y);
  105.     XFreePixmap(dpy,pixmap);
  106.  
  107.     back = RCreateImageFromXImage(scr->rcontext, ximage, NULL);
  108.     XDestroyImage(ximage);
  109.     if (!back) {
  110.         RDestroyImage(icon);
  111.         return;
  112.     }
  113.  
  114.  
  115.     for (i=0,run=0; i<DEMATERIALIZE_STEPS; i++) {
  116.     XEvent foo;
  117.     if (!run && XCheckTypedEvent(dpy, ButtonPress, &foo)) {
  118.         run=1;
  119.         XPutBackEvent(dpy, &foo);
  120.     }
  121.     image = RCloneImage(back);
  122.     RCombineImagesWithOpaqueness(image, icon, 
  123.              (DEMATERIALIZE_STEPS-1-i)*256/(DEMATERIALIZE_STEPS+2));
  124.     RConvertImage(scr->rcontext, image, &pixmap);
  125.     XCopyArea(dpy, pixmap, scr->root_win, gc, 0, 0, w, h, x, y);
  126.     XFreePixmap(dpy, pixmap);
  127.     XFlush(dpy);
  128.     if(!run) wusleep(1000);
  129.     }
  130.  
  131.     while (XCheckTypedEvent(dpy, MotionNotify, &event)) {
  132.     }
  133.     XFlush(dpy);
  134.  
  135.     XUngrabServer(dpy);
  136.     XFreeGC(dpy, gc);
  137.     RDestroyImage(icon);
  138.     RDestroyImage(back);
  139. }
  140. #endif /* DEMATERIALIZE_ICON */
  141.  
  142.  
  143.  
  144.  
  145.  
  146.  
  147. #ifdef NORMAL_ICON_KABOOM
  148. void
  149. DoKaboom(WScreen *scr, Window win, int x, int y)
  150. {
  151.     int i, j, k;
  152.     int sw=scr->scr_width, sh=scr->scr_height;
  153. #define KAB_PRECISION    4
  154.     int px[PIECES];
  155.     short py[PIECES];
  156. #ifdef ICON_KABOOM_EXTRA
  157.     short ptx[2][PIECES], pty[2][PIECES];
  158.     int ll;
  159. #endif
  160.     char pvx[PIECES], pvy[PIECES];
  161.     /* in MkLinux/PPC gcc seems to think that char is unsigned? */
  162.     signed char ax[PIECES], ay[PIECES];
  163.     Pixmap tmp;
  164.  
  165.     XSetClipMask(dpy, scr->copy_gc, None);
  166.     tmp = XCreatePixmap(dpy, scr->root_win, wPreferences.icon_size, 
  167.             wPreferences.icon_size, scr->depth);
  168.     if (scr->w_visual == DefaultVisual(dpy, scr->screen))
  169.     XCopyArea(dpy, win, tmp, scr->copy_gc, 0, 0, wPreferences.icon_size,
  170.           wPreferences.icon_size, 0, 0);
  171.     else {
  172.     XImage *image;
  173.  
  174.     image = XGetImage(dpy, win, 0, 0, wPreferences.icon_size,
  175.               wPreferences.icon_size, AllPlanes, ZPixmap);
  176.     if (!image) {
  177.         XUnmapWindow(dpy, win);
  178.         return;
  179.     }
  180.     XPutImage(dpy, tmp, scr->copy_gc, image, 0, 0, 0, 0, 
  181.           wPreferences.icon_size, wPreferences.icon_size);
  182.     XDestroyImage(image);
  183.     }
  184.  
  185.     for (i=0,k=0; i<wPreferences.icon_size/ICON_KABOOM_PIECE_SIZE && k<PIECES;
  186.      i++) {
  187.     for (j=0; j<wPreferences.icon_size/ICON_KABOOM_PIECE_SIZE && k<PIECES;
  188.          j++) {
  189.         if (rand()%2) {
  190.         ax[k]=i;
  191.         ay[k]=j;
  192.         px[k]=(x+i*ICON_KABOOM_PIECE_SIZE)<<KAB_PRECISION;
  193.         py[k]=y+j*ICON_KABOOM_PIECE_SIZE;
  194.         pvx[k]=rand()%(1<<(KAB_PRECISION+3))-(1<<(KAB_PRECISION+3))/2;
  195.                 pvy[k]=-15-rand()%7;
  196. #ifdef ICON_KABOOM_EXTRA
  197.         for (ll=0; ll<2; ll++) {
  198.             ptx[ll][k] = px[k];
  199.             pty[ll][k] = py[k];
  200.         }
  201. #endif
  202.         k++;
  203.         } else {
  204.         ax[k]=-1;
  205.         }
  206.     }
  207.     }
  208.  
  209.     XUnmapWindow(dpy, win);
  210.  
  211.     j=k;
  212.     while (k>0) {
  213.     XEvent foo;
  214.  
  215.     if (XCheckTypedEvent(dpy, ButtonPress, &foo)) {
  216.         XPutBackEvent(dpy, &foo);
  217.         XClearWindow(dpy, scr->root_win);
  218.         break;
  219.     }
  220.  
  221.     for (i=0; i<j ; i++) {
  222.         if (ax[i]>=0) {
  223.         int _px = px[i]>>KAB_PRECISION;
  224. #ifdef ICON_KABOOM_EXTRA
  225.         XClearArea(dpy, scr->root_win, ptx[1][i], pty[1][i],
  226.                ICON_KABOOM_PIECE_SIZE, ICON_KABOOM_PIECE_SIZE,
  227.                False);
  228.  
  229.         ptx[1][i] = ptx[0][i];
  230.         pty[1][i] = pty[0][i];
  231.         ptx[0][i] = _px;
  232.         pty[0][i] = py[i];
  233. #else
  234.         XClearArea(dpy, scr->root_win, _px, py[i],
  235.                ICON_KABOOM_PIECE_SIZE, ICON_KABOOM_PIECE_SIZE,
  236.                False);
  237. #endif
  238.         px[i]+=pvx[i];
  239.         py[i]+=pvy[i];
  240.         _px = px[i]>>KAB_PRECISION;
  241.                 pvy[i]++;
  242.                 if (_px<-wPreferences.icon_size || _px>sw || py[i]>=sh) {
  243. #ifdef ICON_KABOOM_EXTRA
  244.             if (py[i]>sh && _px<sw && _px>0) {
  245.             pvy[i] = -(pvy[i]/2);
  246.             if (abs(pvy[i]) > 3) {
  247.                 py[i] = sh-ICON_KABOOM_PIECE_SIZE;
  248.                 XCopyArea(dpy, tmp, scr->root_win, scr->copy_gc,
  249.                       ax[i]*ICON_KABOOM_PIECE_SIZE, 
  250.                       ay[i]*ICON_KABOOM_PIECE_SIZE,
  251.                       ICON_KABOOM_PIECE_SIZE, 
  252.                       ICON_KABOOM_PIECE_SIZE,
  253.                       _px, py[i]);
  254.             } else {
  255.                 ax[i] = -1;
  256.             }
  257.             } else {
  258.             ax[i] = -1;
  259.             }
  260.             if (ax[i]<0) {
  261.             for (ll=0; ll<2; ll++)
  262.                 XClearArea(dpy, scr->root_win, ptx[ll][i], pty[ll][i],
  263.                        ICON_KABOOM_PIECE_SIZE, 
  264.                        ICON_KABOOM_PIECE_SIZE, False);
  265.             k--;
  266.             }
  267. #else /* !ICON_KABOOM_EXTRA */
  268.                     ax[i]=-1;
  269.             k--;
  270. #endif /* !ICON_KABOOM_EXTRA */
  271.         } else {
  272.             XCopyArea(dpy, tmp, scr->root_win, scr->copy_gc, 
  273.                   ax[i]*ICON_KABOOM_PIECE_SIZE, ay[i]*ICON_KABOOM_PIECE_SIZE,
  274.                   ICON_KABOOM_PIECE_SIZE, ICON_KABOOM_PIECE_SIZE,
  275.                   _px, py[i]);
  276.         }
  277.         }
  278.     }
  279.  
  280.     XFlush(dpy);
  281. #ifdef SPEAKER_SOUND
  282.     play(dpy, 100+rand()%250, 12);
  283. #else
  284. # if (MINIATURIZE_ANIMATION_DELAY_Z > 0)    
  285.     wusleep(MINIATURIZE_ANIMATION_DELAY_Z*2);
  286. # endif
  287. #endif
  288.     }
  289.     
  290.     XFreePixmap(dpy, tmp);
  291. }
  292. #endif /* NORMAL_ICON_KABOOM */
  293.  
  294.  
  295. Pixmap
  296. MakeGhostDock(WDock *dock, int sx, int dx, int y)
  297. {
  298.     WScreen *scr = dock->screen_ptr;
  299.     XImage *img;
  300.     RImage *back, *dock_image;
  301.     Pixmap pixmap;
  302.     int i, virtual_tiles, h, j, n;
  303.     unsigned long red_mask, green_mask, blue_mask;
  304.  
  305.     virtual_tiles = 0;
  306.     for (i=0; i<dock->max_icons; i++) {
  307.         if (dock->icon_array[i]!=NULL &&
  308.             dock->icon_array[i]->yindex > virtual_tiles)
  309.             virtual_tiles = dock->icon_array[i]->yindex;
  310.     }
  311.     virtual_tiles++;
  312.     h = virtual_tiles * wPreferences.icon_size;
  313.     h = (y + h > scr->scr_height) ? scr->scr_height-y : h;
  314.     virtual_tiles = h / wPreferences.icon_size; /* The visible ones */
  315.     if (h % wPreferences.icon_size)
  316.         virtual_tiles++;  /* There is one partially visible tile at end */
  317.     
  318.     img=XGetImage(dpy, scr->root_win, dx, y, wPreferences.icon_size, h,
  319.                   AllPlanes, ZPixmap);
  320.     if (!img)
  321.       return None;
  322.  
  323.     red_mask = img->red_mask;
  324.     green_mask = img->green_mask;
  325.     blue_mask = img->blue_mask;
  326.     
  327.     back = RCreateImageFromXImage(scr->rcontext, img, NULL);
  328.     XDestroyImage(img);
  329.     if (!back) {
  330.     return None;
  331.     }
  332.  
  333.     for (i=0;i<dock->max_icons;i++) {
  334.         if (dock->icon_array[i]!=NULL &&
  335.             dock->icon_array[i]->yindex < virtual_tiles) {
  336.             Pixmap which;
  337.             j = dock->icon_array[i]->yindex * wPreferences.icon_size;
  338.             n = (h - j < wPreferences.icon_size) ? h - j :
  339.                                                    wPreferences.icon_size;
  340.             if (dock->icon_array[i]->icon->pixmap)
  341.                 which = dock->icon_array[i]->icon->pixmap;
  342.             else
  343.                 which = dock->icon_array[i]->icon->core->window;
  344.  
  345.             img=XGetImage(dpy, which, 0, 0, wPreferences.icon_size, n,
  346.                           AllPlanes, ZPixmap);
  347.  
  348.             if (!img){
  349.                 RDestroyImage(back);
  350.                 return None;
  351.             }
  352.             img->red_mask = red_mask;
  353.             img->green_mask = green_mask;
  354.             img->blue_mask = blue_mask;
  355.  
  356.             dock_image = RCreateImageFromXImage(scr->rcontext, img, NULL);
  357.             XDestroyImage(img);
  358.             if (!dock_image) {
  359.                 RDestroyImage(back);
  360.                 return None;
  361.             }
  362.             RCombineAreaWithOpaqueness(back, dock_image, 0, 0,
  363.                                        wPreferences.icon_size, n,
  364.                                        0, j, 30 * 256 / 100);
  365.             RDestroyImage(dock_image);
  366.         }
  367.     }
  368.  
  369.  
  370.     RConvertImage(scr->rcontext, back, &pixmap);
  371.     
  372.     RDestroyImage(back);
  373.     
  374.     return pixmap;
  375. }
  376.  
  377.  
  378. Pixmap
  379. MakeGhostIcon(WScreen *scr, Drawable drawable)
  380. {
  381.     RImage *back;
  382.     RColor color;
  383.     Pixmap pixmap;
  384.  
  385.  
  386.     if (!drawable)
  387.     return None;
  388.     
  389.     back = RCreateImageFromDrawable(scr->rcontext, drawable, None);
  390.     if (!back) 
  391.     return None;
  392.     
  393.     color.red = 0xff;
  394.     color.green = 0xff;
  395.     color.blue = 0xff;
  396.     color.alpha = 200;
  397.  
  398.     RClearImage(back, &color);
  399.     RConvertImage(scr->rcontext, back, &pixmap);
  400.     
  401.     RDestroyImage(back);
  402.     
  403.     return pixmap;
  404. }
  405.  
  406.  
  407.  
  408. #ifdef WINDOW_BIRTH_ZOOM
  409. void
  410. DoWindowBirth(WWindow *wwin)
  411. {
  412.     int width = wwin->frame->core->width;
  413.     int height = wwin->frame->core->height;
  414.     int w = WMIN(width, 20);
  415.     int h = WMIN(height, 20); 
  416.     int x, y;
  417.     int dw, dh;
  418.     int i;
  419.     time_t time0 = time(NULL);
  420.  
  421.     dw = (width-w)/WINDOW_BIRTH_STEPS;
  422.     dh = (height-h)/WINDOW_BIRTH_STEPS;
  423.  
  424.     x = wwin->frame_x + (width-w)/2;
  425.     y = wwin->frame_y + (height-h)/2;
  426.  
  427.     XMoveResizeWindow(dpy, wwin->frame->core->window, x, y, w, h);
  428.     
  429.     XMapWindow(dpy, wwin->frame->core->window);
  430.     
  431.     XFlush(dpy);
  432.     for (i=0; i<WINDOW_BIRTH_STEPS; i++) {
  433.     x -= dw/2 + dw%2;
  434.     y -= dh/2 + dh%2;
  435.     w += dw;
  436.     h += dh;
  437.     XMoveResizeWindow(dpy, wwin->frame->core->window, x, y, w, h);
  438.     XFlush(dpy);
  439.     /* a timeout */
  440.     if (time(NULL)-time0 > MAX_ANIMATION_TIME)
  441.         break;
  442.     }
  443.  
  444.     XMoveResizeWindow(dpy, wwin->frame->core->window,
  445.               wwin->frame_x, wwin->frame_y, width, height);
  446.     XFlush(dpy);
  447. }
  448. #else
  449. void
  450. DoWindowBirth(WWindow *wwin)
  451. {
  452.     /* dummy stub */
  453. }
  454. #endif
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461. #ifdef SILLYNESS
  462. static WMPixmap *data[12];
  463.  
  464.  
  465. static Bool
  466. loadData(WScreen *scr)
  467. {
  468. #ifdef needs_update
  469.     FILE *f;
  470.     int i;
  471.     RImage *image;
  472.     Pixmap d[12];
  473.  
  474.     return False;
  475.  
  476.     f = fopen(PKGDATADIR"/xtree.dat", "r");
  477.     if (!f)
  478.     return False;
  479.  
  480.     image = RCreateImage(50, 50, False);
  481.     if (!image) {
  482.     fclose(f);
  483.     return False;
  484.     }
  485.  
  486.     for (i = 0; i < 12; i++) {
  487.     if (fread(image->data[0], 50*50, 1, f)!=1) {
  488.         goto error;
  489.     }
  490.     if (fread(image->data[1], 50*50, 1, f)!=1) {
  491.         goto error;
  492.     }
  493.     if (fread(image->data[2], 50*50, 1, f)!=1) {
  494.         goto error;
  495.     }
  496.     if (!RConvertImage(scr->rcontext, image, &(d[i]))) {
  497.         goto error;
  498.     }
  499.     }
  500.     RDestroyImage(image);
  501.  
  502.     fclose(f);
  503.  
  504.     for (i=0; i<12; i++) {
  505.     data[i] = WMCreatePixmapFromXPixmaps(scr->wmscreen, d[i], None, 50, 50, 
  506.                          scr->w_depth);
  507.     }
  508.  
  509.     return True;
  510.  
  511. error:
  512.     RDestroyImage(image);
  513.  
  514.     fclose(f);
  515.  
  516.     while (--i > 0) {
  517.     XFreePixmap(dpy, d[i]);
  518.     }
  519. #endif
  520.     return False;
  521. }
  522.  
  523.  
  524. WMPixmap*
  525. DoXThing(WWindow *wwin)
  526. {
  527.     static int order = 0;
  528.  
  529.     order++;
  530.  
  531.     return data[order % 12];
  532. }
  533.  
  534.  
  535. Bool
  536. InitXThing(WScreen *scr)
  537. {
  538.     time_t t;
  539.     struct tm *l;
  540.     static int i = 0;
  541.  
  542.     if (i)
  543.     return True;
  544.  
  545.     t = time(NULL);
  546.     l = localtime(&t);
  547.     if ((l->tm_mon!=11||l->tm_mday<24||l->tm_mday>26)) {
  548.     return False;
  549.     }
  550.  
  551.     if (!loadData(scr))
  552.     return False;
  553.  
  554.     i = 1;
  555.     
  556.     return True;
  557. }
  558.  
  559. #endif /* SILLYNESS */
  560.  
  561.  
  562. #ifdef GHOST_WINDOW_MOVE
  563.  
  564. typedef struct {
  565.     WScreen *scr;
  566.  
  567.     int width, height;
  568.  
  569.     int iniX, iniY;
  570.     int boxX, boxY;
  571.  
  572.     Window window;
  573.  
  574.     RXImage *winImage;
  575.  
  576.     RXImage *backImage;
  577.  
  578.     /* the combined image */
  579.     RXImage *image;
  580.     Pixmap pixmap;
  581.  
  582. } _GhostWindowData;
  583.  
  584.  
  585.  
  586. _GhostWindowData*
  587. InitGhostWindowMove(WWindow *wwin)
  588. {
  589.     _GhostWindowData *gdata;
  590.     WScreen *scr = wwin->screen_ptr;
  591.     unsigned short *ptr;
  592.     unsigned short mask;
  593.     int i;
  594.  
  595.     gdata = wmalloc(sizeof(_GhostWindowData));
  596.  
  597.     gdata->width = wwin->frame->core->width;
  598.     gdata->height = wwin->frame->core->height;
  599.  
  600.     gdata->iniX = wwin->frame_x;
  601.     gdata->iniY = wwin->frame_y;
  602.  
  603.     gdata->boxX = wwin->frame_x;
  604.     gdata->boxY = wwin->frame_y;
  605.  
  606.     gdata->window =
  607.     XCreateSimpleWindow(dpy, scr->root_win, wwin->frame_x, wwin->frame_y,
  608.                 gdata->width, gdata->height, 0, 0, 0);
  609.  
  610.     gdata->winImage = RGetXImage(scr->rcontext, wwin->frame->core->window, 
  611.                  0, 0, gdata->width, gdata->height);
  612.  
  613.     gdata->backImage = RCreateXImage(scr->rcontext, scr->w_depth, 
  614.                      gdata->width, gdata->height);
  615.  
  616.     memcpy(gdata->backImage->image->data, gdata->winImage->image->data,
  617.        gdata->winImage->image->bytes_per_line * gdata->height);
  618.  
  619.     gdata->image = RCreateXImage(scr->rcontext, scr->w_depth,
  620.                  gdata->width, gdata->height);
  621.  
  622.     ptr = (unsigned short*)gdata->winImage->image->data;
  623.  
  624.     mask = 0x7b00|0x3d0|0x1e;
  625.  
  626.     for (i = 0;
  627.      i < gdata->winImage->image->bytes_per_line * gdata->height;
  628.      i++, ptr++) {
  629.  
  630.     *ptr &= mask;
  631.     }
  632.  
  633.     return gdata;
  634. }
  635.  
  636.  
  637. static void
  638. mergeGhostWindow(_GhostWindowData *gdata)
  639. {
  640.     register unsigned short *ptrw, *ptrb, *ptr;
  641.     int count;
  642.     int i;
  643.  
  644.     ptr = (unsigned short*)gdata->image->image->data;
  645.     ptrw = (unsigned short*)gdata->winImage->image->data;
  646.     ptrb = (unsigned short*)gdata->backImage->image->data;
  647.  
  648.     count = gdata->winImage->image->bytes_per_line * gdata->height;
  649.  
  650.     while (count--) {
  651.     *ptr = (*ptrw + *ptrb) >> 1;
  652.  
  653.     ptr++;
  654.     ptrw++;
  655.     ptrb++;
  656.     }
  657. }
  658.  
  659.  
  660. void
  661. UpdateGhostWindowMove(void *data, int x, int y)
  662. {
  663.     _GhostWindowData *gdata = (_GhostWindowData*)data;
  664.     WScreen *scr = gdata->scr;
  665.  
  666.     /* no intersection of new background with current */
  667.     if (x + gdata->width <= gdata->boxX 
  668.     || x >= gdata->boxX + gdata->width
  669.     || y + gdata->height <= gdata->boxY
  670.     || y >= gdata->boxY + gdata->height) {
  671.     int i;
  672.  
  673.     RDestroyXImage(gdata->backImage);
  674.  
  675.     gdata->backImage = RGetXImage(scr->rcontext, scr->root_win, x, y,
  676.                       gdata->width, gdata->height);
  677.  
  678.     ptr = (unsigned short*)gdata->backImage->image->data;
  679.  
  680.     mask = 0x7b00|0x3d0|0x1e;
  681.  
  682.     for (i = 0;
  683.          i < gdata->winImage->image->bytes_per_line * gdata->height;
  684.          i++, ptr++) {
  685.  
  686.         *ptr &= mask;
  687.     }
  688.     } else {
  689.     int hx, hw, hy, hh;
  690.     int vx, vw, vy, vh;
  691.     int i, j;
  692.     unsigned char *backP = gdata->backImage->image->data;
  693.     unsigned char *winP = gdata->winImage->image->data;
  694.     int backLineLen = gdata->backImage->image->bytes_per_line;
  695.     int winLineLen = gdata->winImage->image->bytes_per_line;
  696.  
  697.     /* 1st move the area of the current backImage that overlaps
  698.      * the new backImage to it's new position */
  699.  
  700.     if (x < gdata->boxX) {
  701.         vx = x + gdata->width;
  702.         vw = gdata->width - vx;
  703.     } else if (x > gdata->boxX) {
  704.         vw = gdata->boxX + gdata->width - x;
  705.         vx = gdata->boxX - vw;
  706.     } else {
  707.         vx = 0;
  708.         vw = gdata->width;
  709.     }
  710.  
  711.     if (y < gdata->boxY) {
  712.         vy = y + gdata->height;
  713.         vh = gdata->height - vy;
  714.     } else if (y > gdata->boxY) {
  715.         vh = gdata->boxY + gdata->height - y;
  716.         vy = gdata->boxY - vh;
  717.     } else {
  718.         vy = 0;
  719.         vh = gdata->height;
  720.     }
  721.  
  722.     if (y < gdata->boxY) {
  723.         int dy = vy - gdata->boxY;
  724.  
  725.         if (x < gdata->boxX) {
  726.         for (i = vh - 1; i >= 0; i--) {
  727.             memmove(&backP[(i + dy) * backLineLen + 2 * vx],
  728.                 &backP[i * backLineLen], 2 * vw);
  729.         }
  730.         } else /* if (x > gdata->boxX) */ {
  731.         for (i = vh - 1; i >= 0; i--) {
  732.             memmove(&backP[(i + dy) * backLineLen],
  733.                 &backP[i * backLineLen + 2 * vx], 2 * vw);
  734.         }
  735.         }
  736.     } else /*if (y > gdata->boxY) */ {
  737.         int dy = gdata->boxY - vy;
  738.  
  739.         if (x < gdata->boxX) {
  740.         for (i = 0; i < vh - 1; i++) {
  741.             memmove(&backP[i * backLineLen + 2 * vx], 
  742.                 &backP[(i + dy) * backLineLen], 2 * vw);
  743.         }
  744.         } else /*if (x > gdata->boxX) */ {
  745.         for (i = 0; i < vh - 1; i++) {
  746.             memmove(&backP[i * backLineLen], 
  747.                 &backP[(i + dy) * backLineLen + 2 * vx], 2 * vw);
  748.         }
  749.         }
  750.     }
  751.  
  752.     /* 2nd grab the background image from the screen and copy to the
  753.      * buffer. also maskout the lsb of rgb in each pixel of grabbed data */
  754.  
  755.     if (y < gdata->boxY) {
  756.         vy = y;
  757.         vh = gdata->boxY - vy;
  758.  
  759.         hy = y + vh;
  760.         hh = gdata->height - vh;
  761.     } else if (y > gdata->boxY) {
  762.         vy = gdata->boxY + gdata->height;
  763.         vh = vy - (y + gdata->height);
  764.  
  765.         hy = y;
  766.         hh = y - gdata->boxY;
  767.     } else {
  768.         vy = vh = 0;
  769.  
  770.         hy = y;
  771.         hh = gdata->height;
  772.     }
  773.  
  774.     if (x < gdata->boxX) {
  775.         hx = x;
  776.         hw = gdata->boxX - hx;
  777.     } else if (x > gdata->boxX) {
  778.         hx = gdata->boxX + gdata->width;
  779.         hw = hx - (x + gdata->width);
  780.     } else {
  781.         hx = hw = 0;
  782.  
  783.         vx = x;
  784.         vw = gdata->width;
  785.     }
  786.  
  787.     /* 1st the top/bottom part */
  788.  
  789.     
  790.  
  791.     /* 2nd the left/right part */
  792.     }
  793.  
  794.     mergeGhostWindow(gdata);
  795. }
  796.  
  797.  
  798. #endif /* GHOST_WINDOW_MOVE */
  799.  
  800.